package main

import (
	"errors"
	"sync"
)

type Room struct {
	key string
	channels *LinkList
}

type RoomMap struct{
	sync.Mutex
	rmap map[string]*Room
}

var RoomMapI *RoomMap

func InitRoomMap(){
	RoomMapI = &RoomMap{}
	RoomMapI.rmap = make(map[string]*Room)
}

func JoinRoom(channel *Channel,roomid string) {

	RoomMapI.Lock()
	defer RoomMapI.Unlock()
	room,ok := RoomMapI.rmap[roomid]
	if !ok{
		room = &Room{key:roomid,channels:NewLinkList()}
		RoomMapI.rmap[roomid] = room
	}
	room.channels.Append(channel)
	channel.rooms.Append(roomid)
}

func LeaveRoom(channel *Channel,roomid string) error{
	RoomMapI.Lock()
	defer RoomMapI.Unlock()
	room,ok := RoomMapI.rmap[roomid]
	if !ok{
		return errors.New("Roomid not exist")
	}
	room.channels.Remove(channel)
	channel.rooms.Remove(roomid)
	return nil
}
func LeaveAllRoom(channel *Channel){
	RoomMapI.Lock()
	defer RoomMapI.Unlock()
	roomNode := channel.rooms.root
	for {
		if roomNode == nil{
			break
		}
		roomid, ok := roomNode.value.(string)
		room, ok := RoomMapI.rmap[roomid]
		if !ok {
			return
		}
		room.channels.Remove(channel)
		channel.rooms.Remove(roomid)
		roomNode = roomNode.next
	}
}

func PushToRoom(msg *Msg,roomid string) error{
	//TODO   use chan & goroutine
	RoomMapI.Lock()
	defer RoomMapI.Unlock()
	room,ok := RoomMapI.rmap[roomid]
	if !ok{
		return errors.New("roomid is not exist")
	}

	node:= room.channels.root
	for {
		if node == nil{
			break
		}
		channel,cok := node.value.(*Channel)
		if !cok{
			break
		}
		msg.From = channel.token
		channel.PushMsg(msg)
		node = node.next
	}
	return nil
}





